/*
 * av_format.cpp
 *
 *  Created on: 2012-7-11
 *      Author: ThinkPad
 */

#include "av_format.h"

static const char *FLVHeader = "FLV\x1\x1\0\0\0\x9\0\0\0\x9";

av_format::av_format(void)
{
    //add your code here
}

av_format::~av_format(void)
{
   //add your code here
}

int av_format::read_flv_header(int filefd,ubyte * pbuf,size_t buf_size)
{
    if(filefd < 0 || pbuf == NULL || buf_size < 64)
         return 0;

    int   ret_value = 0;
    off_t Offset;
    u_char buf[FLV_TAG_HEADER_LEN + 8];
    u_int read_size;
    u_int tag_type = 0,tag_size = 0,tag_count = 0,vidoe_flag = 0,v_size = 0,audio_flag = 0,a_size = 0,data_len = 0;
    Offset = FLV_FILE_HEADER_LEN;
    lseek(filefd,Offset,SEEK_SET);
    bool is_fh264 = false;
    while((read_size = read(filefd,buf,FLV_TAG_HEADER_LEN + 8)) > 0)
    {
        tag_count++;
        /*copy tag*/
        tag_type = utils::read_8(buf+4);
        tag_size = utils::read_24(buf+5);
        /*check valied video tag*/
        if (tag_type != 18 && tag_type != 8 && tag_type != 9)
        {
            break;
        }
        /*get audio decode args*/
        if(tag_type == 8 && audio_flag == 0 && tag_size < 32)
        {
            data_len += tag_size + FLV_TAG_HEADER_LEN;
            audio_flag = Offset;
            a_size = tag_size + FLV_TAG_HEADER_LEN;
        }
        /*get video decode args*/
        if(tag_type == 9 && vidoe_flag == 0 && tag_size < 2048)
        {
            data_len += tag_size + FLV_TAG_HEADER_LEN;
            vidoe_flag = Offset ;
            v_size = tag_size + FLV_TAG_HEADER_LEN;

            if((buf[FLV_TAG_HEADER_LEN] & 0x0f)  == 0x07)
            {
                is_fh264 = true;
            }
            else
            {
                is_fh264 = false;
                break;
            }
        }
        /*get set file position args*/
        Offset += tag_size + FLV_TAG_HEADER_LEN;
        if(lseek(filefd,Offset,SEEK_SET) < 0)
        {
            break;
        }
        /*check get all tag data*/
        if((audio_flag != 0 && vidoe_flag !=0) || tag_count > 4)
            break;
    }
    /*copy header*/
    memcpy(pbuf,FLVHeader,FLV_FILE_HEADER_LEN);
    ret_value =  FLV_FILE_HEADER_LEN;
    /*copy data*/
    if(is_fh264 && audio_flag != 0 && vidoe_flag !=0)
    {
        /*get data*/
        Offset = audio_flag;
        if(lseek(filefd,Offset,SEEK_SET) >= 0)
        {
            if((read_size = read(filefd,pbuf  + ret_value,a_size)) > 0)
            {
                ret_value += a_size ;
            }
            else
            {
                return -1;
            }
        }
        else
        {
            return -2;
        }
        Offset = vidoe_flag;
        if(lseek(filefd,Offset,SEEK_SET) >= 0)
        {
            if((read_size = read(filefd,pbuf + ret_value,v_size)) > 0)
            {
                ret_value += v_size ;
            }
            else
            {
                return -3;
            }
        }
        else
        {
            return -4;
        }
    }
    /*file position reset to zero*/
    Offset = 0;
    if(lseek(filefd,Offset,SEEK_SET) < 0)
    {
        ret_value = -5;
    }

    return ret_value;
}
